
package com.caration.shell.preference;

import com.caration.sdk.utilities.Logger;

import android.R;
import android.content.Context;
import android.graphics.Typeface;
import android.preference.Preference;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

/**
 * A {@link preference} contains {@link SeekBar}
 * 
 * @author Lonn
 */
public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
    private final int FILL = LayoutParams.FILL_PARENT;
    private final int WRAP = LayoutParams.WRAP_CONTENT;
    private SeekBar mSeekBar;
    private TextView mSeekBarValue;
    private TextView mUnitsLeft;
    private TextView mUnitsRight;
    private int mMinValue;
    private int mMaxValue;
    private int mProgress;
    private String mUnitsLeftStr;
    private String mUnitsRightStr;
    private boolean isOppositeDependency;

    public SeekBarPreference(Context context) {
        this(context, null);
    }

    public SeekBarPreference(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (mSeekBar == null) {
            mSeekBar = new SeekBar(context);
            mSeekBar.setOnSeekBarChangeListener(this);
        }
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
        final View layout = createView();
        return layout;
    }

    /**
     * <p>
     * Create layout view
     * </p>
     * You must set
     * <p>
     * <b>android.R.widget_frame</b> as root view id
     * </p>
     * <p>
     * <b>android.R.title</b> as title textview id
     * </p>
     * <p>
     * <b>android.R.summary</b> as summary textview id
     * </p>
     * 
     * @return layout
     */
    protected View createView() {
        Logger.e("createView");
        LayoutParams fillParams = new LayoutParams(FILL, WRAP);
        LayoutParams wrapParams = new LayoutParams(WRAP, WRAP);
        final Context context = getContext();

        RelativeLayout root = new RelativeLayout(context);
        root.setId(R.id.widget_frame);
        root.setPadding(15, 5, 10, 5);

        TextView title = new TextView(context);
        title.setId(android.R.id.title);
        title.setTextAppearance(context, R.attr.textAppearanceLarge);
        title.setTextSize(18);
        title.setEllipsize(TruncateAt.MARQUEE);
        title.setHorizontalFadingEdgeEnabled(true);
        title.setSingleLine();

        TextView summary = new TextView(context);
        summary.setId(android.R.id.summary);
        summary.setTextAppearance(context, R.attr.textAppearanceSmall);
        summary.setMaxLines(2);
        LayoutParams summaryParams = new LayoutParams(wrapParams);
        summaryParams.addRule(RelativeLayout.BELOW, R.id.title);
        summaryParams.addRule(RelativeLayout.ALIGN_LEFT, R.id.title);

        mUnitsRight = new TextView(context);
        mUnitsRight.setId(R.id.text1);
        LayoutParams unitsRightParams = new LayoutParams(wrapParams);
        unitsRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        unitsRightParams.addRule(RelativeLayout.BELOW, R.id.title);

        mSeekBarValue = new TextView(context);
        mSeekBarValue.setId(R.id.text2);
        mSeekBarValue.setGravity(Gravity.RIGHT);
        LayoutParams skbarValueParams = new LayoutParams(wrapParams);
        skbarValueParams.addRule(RelativeLayout.BELOW, R.id.title);
        skbarValueParams.addRule(RelativeLayout.LEFT_OF, R.id.text1);

        mUnitsLeft = new TextView(context);
        LayoutParams unitsLeftParams = new LayoutParams(wrapParams);
        unitsLeftParams.addRule(RelativeLayout.BELOW, R.id.summary);
        unitsLeftParams.addRule(RelativeLayout.LEFT_OF, R.id.text2);

        LinearLayout seekRoot = new LinearLayout(context);
        LayoutParams seekRootParams = new LayoutParams(fillParams);
        seekRootParams.setMargins(10, 0, 10, 0);
        seekRootParams.addRule(RelativeLayout.BELOW, R.id.text2);
        seekRootParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        seekRootParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);

        if (mSeekBar.getParent() != null) {
            ((ViewGroup) mSeekBar.getParent()).removeView(mSeekBar);
        }
        seekRoot.addView(mSeekBar, new LayoutParams(FILL, WRAP));

        root.addView(title, wrapParams);
        root.addView(summary, summaryParams);
        root.addView(mUnitsRight, unitsRightParams);
        root.addView(mSeekBarValue, skbarValueParams);
        root.addView(mUnitsLeft, unitsLeftParams);
        root.addView(seekRoot, seekRootParams);

        return root;
    }

    public void setOppositeDependency(boolean isOpposite) {
        isOppositeDependency = isOpposite;
    }

    public void setUnitsLeft(String units) {
        mUnitsLeftStr = units;
    }

    public void setUnitsRight(String units) {
        mUnitsRightStr = units;
    }

    /**
     * Set the minimum value of seekbar
     * 
     * @param min
     */
    public void setMinSeek(int min) {
        mMinValue = min;
    }

    /**
     * Set the maximum value of seekbar
     * 
     * @param max
     */
    public void setMaxSeek(int max) {
        mMaxValue = max;
    }

    @Override
    protected void onBindView(View view) {
        super.onBindView(view);
        Logger.e("onBindView");
        mSeekBar.setMax(mMaxValue - mMinValue);
        seek(mProgress);
        mSeekBarValue.setText(Integer.toString(mProgress));
        mUnitsLeft.setText(mUnitsLeftStr);
        mUnitsRight.setText(mUnitsRightStr);
    }

    /**
     * Seek to target position
     * 
     * @param progress the progress of seekbar
     */
    public void seek(int progress) {
        if (progress < mMinValue) {
            progress = mMinValue;
        }
        mSeekBar.setProgress(progress - mMinValue);
    }

    /**
     * get the progress of seekbar
     * 
     * @return progress
     */
    public int getProgress() {
        return mProgress;
    }

    @Override
    public void onDependencyChanged(Preference dependency, boolean disableDependent) {
        boolean disable = isOppositeDependency ? !disableDependent : disableDependent;
        if (mSeekBar != null) {
            mSeekBar.setEnabled(disable);
        }
        super.onDependencyChanged(dependency, disable);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        mProgress = progress + mMinValue;
        if (mSeekBarValue != null)
            mSeekBarValue.setText(Integer.toString(mProgress));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        notifyChanged();
    }

}
